Completely change the way language handling works in the GUI.
authorrobertlipe@gmail.com <robertlipe@gmail.com@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 4 Sep 2011 21:03:14 +0000 (21:03 +0000)
committerrobertlipe@gmail.com <robertlipe@gmail.com@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 4 Sep 2011 21:03:14 +0000 (21:03 +0000)
git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@4085 f51c46e8-681c-474f-0cfe-069cfd0219fb

gpsbabel/gui/main.cpp
gpsbabel/gui/mainwindow.cpp
gpsbabel/gui/mainwindow.h

index c1dc56a21a327f6127bee768bbd058cb292594b6..0e50b6ed76af9c12039e11707a80b54a14e844f6 100644 (file)
@@ -25,7 +25,6 @@
 #include <QFile>
 #include <QCoreApplication>
 #include <QLibraryInfo>
-#include <QTranslator>
 #include <QIcon>
 
 #include "mainwindow.h"
@@ -41,33 +40,6 @@ const char *pathSeparator = ":";
 #include <CoreFoundation/CoreFoundation.h>
 #endif
 
-//------------------------------------------------------------------------
-static void installTranslation(QApplication *app, const QString &nm)
-{
-  QTranslator *xlator = new QTranslator();
-
-  xlator->load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/" + nm + QLocale::system().name());
-
-  xlator->load(nm + QLocale::system().name());
-
-#if defined (Q_OS_MAC)
-  CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
-  CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef,
-                                           kCFURLPOSIXPathStyle);
-  QString pathPtr(CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding()));
-  pathPtr += "/Contents/MacOS/lang/" + nm;
-  // pathPtr +=  QLocale::system().name().left(2);
-  pathPtr +=  QLocale::system().name();
-
-  xlator->load(pathPtr);
-
-#endif
-
-  app->installTranslator(xlator);
-}
-
-//------------------------------------------------------------------------
-
 //------------------------------------------------------------------------
 int main(int argc, char**argv)
 {
@@ -81,10 +53,6 @@ int main(int argc, char**argv)
   strcpy(newPathEnv, newPath.toStdString().c_str());
   putenv(newPathEnv);
 
-  installTranslation(app, "qt_");
-  installTranslation(app, "gpsbabelfe_");
-  installTranslation(app, "gpsbabel_");
-
   QCoreApplication::setOrganizationName("GPSBabel");
   QCoreApplication::setOrganizationDomain("gpsbabel.org");
   QCoreApplication::setApplicationName("GPSBabel");
@@ -92,5 +60,6 @@ int main(int argc, char**argv)
   MainWindow mainWindow(0);
   mainWindow.show();
   app->exec();
+
   return 0;
 }
index d8f172dec4648732f5481d371d44a331292cb623..42c828c6ff5862459c4c9b2f33d70199bbf73b5c 100644 (file)
@@ -204,6 +204,9 @@ MainWindow::MainWindow(QWidget* parent): QMainWindow(parent)
 
   ui.outputWindow->setReadOnly(true);
 
+  // Start up in the current system language.
+  loadLanguage(QLocale::system().name());
+  createLanguageMenu();
 
   //--- Restore from registry
   restoreSettings();
@@ -228,6 +231,106 @@ MainWindow::~MainWindow()
   if (upgrade)
     delete upgrade;
 }
+//------------------------------------------------------------------------
+// Dynamic language switching courtesy of 
+// http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application
+// We create the menu entries dynamically, dependant on the existing 
+// translations.
+void MainWindow::createLanguageMenu(void)
+{
+    QActionGroup* langGroup = new QActionGroup(ui.menuHelp);
+    langGroup->setExclusive(true);
+    connect(langGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotLanguageChanged(QAction *)));
+
+    // format systems language
+    QString defaultLocale = QLocale::system().name();       // e.g. "de_DE"
+    defaultLocale.truncate(defaultLocale.lastIndexOf('_')); // e.g. "de"
+
+    langPath = QApplication::applicationDirPath();
+    langPath.append("/translations");
+//fprintf(stderr, "Looking in %s\n", qPrintable(langPath));
+    QDir dir(langPath);
+    QStringList fileNames = dir.entryList(QStringList("*.qm"));
+
+    for (int i = 0; i < fileNames.size(); ++i) {
+        // get locale extracted by filename
+        QString locale;
+        locale = fileNames[i];                  // "TranslationExample_de.qm"
+        locale.truncate(locale.lastIndexOf('.'));   // "TranslationExample_de"
+        locale.remove(0, locale.indexOf('_') + 1);   // "de"
+
+        QString lang = QLocale::languageToString(QLocale(locale).language());
+
+        QAction *action = new QAction(lang, this);
+        action->setCheckable(true);
+        action->setData(locale);
+
+        ui.menuHelp->addAction(action);
+        langGroup->addAction(action);
+
+        // set default translators and language checked
+        if (defaultLocale == locale) {
+            action->setChecked(true);
+        }
+    }
+}
+
+//------------------------------------------------------------------------
+// Called every time, when a menu entry of the language menu is called
+void MainWindow::slotLanguageChanged(QAction* action)
+{
+  if (0 != action) {
+    // load the language dependant on the action content.
+    loadLanguage(action->data().toString());
+  }
+}
+
+void switchTranslator(QTranslator& translator, const QString& filename)
+{
+  // remove the old translator
+  qApp->removeTranslator(&translator);
+
+  // load the new translator
+  if (translator.load(filename))
+    qApp->installTranslator(&translator);
+}
+
+void MainWindow::loadLanguage(const QString& rLanguage)
+{
+  if (currLang != rLanguage) {
+    currLang = rLanguage;
+    QLocale locale = QLocale(currLang);
+    QLocale::setDefault(locale);
+    QString languageName = QLocale::languageToString(locale.language());
+    switchTranslator(translator, QString("gpsbabelfe_%1.qm").arg(rLanguage));
+    switchTranslator(translatorCore, QString("gpsbabel__%1.qm").arg(rLanguage));
+    switchTranslator(translatorQt, QString("qt_%1.qm").arg(rLanguage));
+  }
+}
+
+void MainWindow::changeEvent(QEvent* event)
+{
+    if (0 != event) {
+        switch(event->type()) {
+        // This event is sent if a translator is loaded.
+        case QEvent::LanguageChange:
+            ui.retranslateUi(this);
+            break;
+        // This event is sent if the system language changes.
+        case QEvent::LocaleChange:
+            {
+                QString locale = QLocale::system().name();
+                locale.truncate(locale.lastIndexOf('_'));
+                loadLanguage(locale);
+            }
+           break;
+        default:
+           break;
+        }
+    }
+    QMainWindow::changeEvent(event);
+}
 
 //------------------------------------------------------------------------
 void MainWindow::loadInputDeviceNameCombo(const QString &format)
@@ -535,7 +638,7 @@ void MainWindow::loadFormats()
                                "Check that the backend program \"gpsbabel\" is properly installed "
                                "and is in the current PATH\n\n"
                                "This program cannot continue."));
-    exit(1);
+   exit(1);
   }
   if (inputFileFormatIndices().size() == 0 ||
       inputDeviceFormatIndices().size() == 0 ||
@@ -954,7 +1057,7 @@ void MainWindow::closeActionX()
   bd.runCount++;
 
   QDateTime now = QDateTime::currentDateTime();
-  if((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) {
+  if ((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) {
     Donate donate(0);
     if (bd.donateSplashed.date() == QDate(2010,1,1))
       donate.showNever(false);
index 9c449cfe925a13503276b87177c8bb6c728d2880..cf1a283c6cfb6a113d0122147c47c40ea6d71822 100644 (file)
@@ -28,6 +28,8 @@
 #include "babeldata.h"
 #include "upgrade.h"
 
+#include <QTranslator>
+
 class MainWindow: public QMainWindow {
   Q_OBJECT
 
@@ -36,6 +38,7 @@ class MainWindow: public QMainWindow {
   MainWindow(QWidget* parent);
   ~MainWindow();
 
+
 private:
   Ui_MainWindow     ui;
   QList<Format>  formatList;
@@ -46,9 +49,16 @@ private:
   AllFiltersData filterData;
   BabelData      bd;
   bool           fmtChgInterlock;
+  QTranslator     translator;     // translation for the GUI.
+  QTranslator     translatorCore; // translation for the core application.
+  QTranslator     translatorQt;   // translations for Qt.
+  QString         currLang;       // currently loaded language.
+  QString         langPath;       // Path of language files. This is always fixed to /languages. 
 
 private:
   void loadFormats();
+  void loadLanguage(const QString& rLanguage);
+  void createLanguageMenu();
   QString filterForFormat(int idx);
   QString ensureExtensionPresent(const QString &nanme, int idx);
   QString findBabelVersion();
@@ -89,6 +99,7 @@ private:
 
 protected:
   void closeEvent(QCloseEvent*);
+  void changeEvent(QEvent*);
 
  private slots:
   void aboutActionX();
@@ -116,6 +127,8 @@ protected:
   void visitWebsiteActionX();
   void resetFormatDefaults();
   void upgradeCheckActionX();
+  void slotLanguageChanged(QAction* action);
+
 
 };